package com.dd.lnetwork

import android.text.TextUtils
import android.util.Log
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import java.security.KeyManagementException
import java.security.KeyStore
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSession
import javax.net.ssl.TrustManager
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager

class OkHttpClientHelper {
    private val HTTP_READ_TIMEOUT = 30
    private val HTTP_WRITE_TIMEOUT = 30
    private val HTTP_CONNECT_TIMEOUT = 30

    companion object {
        private var instance: OkHttpClientHelper? = null
        fun getInstance(): OkHttpClientHelper {
            return instance ?: synchronized(this) {
                instance ?: OkHttpClientHelper().apply { instance = this }
            }
        }
    }

    fun getOKHttpClient(vararg interceptors: Interceptor): OkHttpClient {
        val builder = OkHttpClient.Builder()
        var sslContext: SSLContext? = null
        try {
            sslContext = SSLContext.getInstance("SSL")
            val x509TrustManager: X509TrustManager = object : X509TrustManager {
                @Throws(CertificateException::class)
                override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
                }

                @Throws(CertificateException::class)
                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
                    try {
                        val factory = TrustManagerFactory.getInstance("X509")
                        factory.init(null as KeyStore)
                        for (trustManager in factory.trustManagers) {
                            (trustManager as X509TrustManager).checkServerTrusted(chain, authType)
                        }
                    } catch (e: NoSuchAlgorithmException) {
                        e.printStackTrace()
                    } catch (e: KeyStoreException) {
                        e.printStackTrace()
                    }
                    try {
                        //获取网络中证书信息
                        val certificate = chain[0]
                        //证书拥有者
                        val subject = certificate.subjectDN.name
                        //证书颁发者
                        //String issuer = certificate.getIssuerDN().getName();
                        Log.e("Http","X509Certificate--$subject")
                        if (TextUtils.isEmpty(subject) ||
                            !subject.contains("*.dazhuanjia.com")
                            && !subject.contains("aliyuncs.com")
                        ) {
                            throw CertificateException()
                        }
                    } catch (e: Exception) {
                        throw CertificateException()
                    }
                }

                override fun getAcceptedIssuers(): Array<X509Certificate> {
                    return arrayOf()
                }
            }
            val trustAllCerts = arrayOf<TrustManager>(x509TrustManager)
            sslContext.init(null, trustAllCerts, SecureRandom())
            val sslSocketFactory = sslContext.socketFactory
            builder.sslSocketFactory(
                sslSocketFactory,
                x509TrustManager
            )
        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        } catch (e: KeyManagementException) {
            e.printStackTrace()
        }

        builder.connectTimeout(HTTP_CONNECT_TIMEOUT.toLong(), TimeUnit.SECONDS)
            .readTimeout(HTTP_READ_TIMEOUT.toLong(), TimeUnit.SECONDS)
            .writeTimeout(HTTP_WRITE_TIMEOUT.toLong(), TimeUnit.SECONDS) //错误重连
            .retryOnConnectionFailure(true)
            .hostnameVerifier { hostname: String, session: SSLSession ->
                hostVerifier(
                    hostname,
                    session
                )
            }
        for (interceptor in interceptors) {
            builder.addInterceptor(interceptor)
        }
        return builder.build()
    }

    private fun hostVerifier(hostname: String, sslSession: SSLSession): Boolean {
        Log.e("HTTP", "X509Certificate-hostname-$hostname")
        if (!TextUtils.isEmpty(hostname)) {
            val isHostnameVerified = (hostname.contains(".dazhuanjia.com")
                    || hostname.contains(".dazhuanjia.net")
                    || hostname.contains(".dazhuanjia.cn")) || "172.29.28.9" == hostname || "172.29.28.26" == hostname || hostname.contains(
                "aliyuncs.com"
            )
            if (isHostnameVerified) {
                return true
            }
        }
        val hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier()
        return hostnameVerifier.verify(hostname, sslSession)
    }
}